/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.saber.certificacao.beansjsf.administracao;

import br.com.saber.certificacao.beansjsf.interfacebean.BeanJSFInterface;
import br.com.saber.certificacao.beansjsf.login.LoginManager;
import br.com.saber.certificacao.beansjsf.semescopo.SelectItemManager;
import br.com.saber.certificacao.ejbs.stateless.interfaces.UsuarioBeanLocal;
import br.com.saber.certificacao.modelos.Roles;
import br.com.saber.certificacao.modelos.Usuario;
import br.com.saber.certificacao.modelos.validadores.exceptions.generica.ValidacaoExcecao;
import br.com.saber.certificacao.observador.ControleObserver;
import br.com.saber.certificacao.utils.UtilMetodos;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
import org.apache.commons.lang.StringUtils;

/**
 *
 * @author gbvbahia
 */
@ManagedBean(name = "admUsuario")
@ViewScoped
public class UserManager implements BeanJSFInterface {

    @EJB
    private UsuarioBeanLocal usuarioBean;

    private Usuario usuarioCadastro;

    private List<Usuario> modelUsuarios;

    private String actionEvent;

    @ManagedProperty("#{loginManager}")
    private LoginManager loginManager;

    @ManagedProperty("#{selectItemManager}")
    private SelectItemManager selectItemManager;

    /** Creates a new instance of UserManager */
    public UserManager() {
    }

    //====================
    // Iniciadores
    //====================
    @Override
    @PostConstruct
    public void init() {
        this.usuarioCadastro = new Usuario();
        usuarioCadastro.setUsuarioResponsavel(loginManager.getUsuario());
        Logger.getLogger(this.getClass().getName()).log(Level.FINEST, "UserManager.init() executado!");
    }

    @Override
    @PreDestroy
    public void end() {
        Logger.getLogger(this.getClass().getName()).log(Level.FINEST, "UserManager.end() executado!");
    }

    //====================
    //Métodos de Negócio
    //====================
    public void reset(ActionEvent event) {
        cleanSubmittedValues(event.getComponent());
    }

    private void cleanSubmittedValues(UIComponent component) {
        if (component instanceof EditableValueHolder) {
            EditableValueHolder evh = (EditableValueHolder) component;
            evh.setSubmittedValue(null);
            evh.setValue(null);
            evh.setLocalValueSet(false);
            evh.setValid(true);
        } else if (component.getChildCount() > 0) {
            for (UIComponent child : component.getChildren()) {
                cleanSubmittedValues(child);
            }
        } else if (component.getParent() != null) {
            cleanSubmittedValues(component.getParent());
        }
    }

    public void salvarUsuario(ActionEvent event) {
        try {
            boolean novoUser = (usuarioCadastro.getId() == null);
            if(this.loginManager != null && this.loginManager.getUsuario() != null && this.usuarioCadastro.getUsuarioResponsavel() == null)
                this.usuarioCadastro.setUsuarioResponsavel(this.loginManager.getUsuario());
            usuarioBean.salvarUsuario(usuarioCadastro, UtilMetodos.getURL(FacesContext.getCurrentInstance()));
            init();
            ControleObserver.notificaObservers(loginManager.getUsuario(), new String[]{ControleObserver.Eventos.CAD_USUARIO_EVENT});
            if (usuarioCadastro.isBloqueado()) {
                UtilMetodos.messageFactoringFull("usuarioCadastradoBloqueado", FacesMessage.SEVERITY_INFO, FacesContext.getCurrentInstance());
            } else if (!novoUser) {
                UtilMetodos.messageFactoringFull("usuarioEditadoOk", FacesMessage.SEVERITY_INFO, FacesContext.getCurrentInstance());
            } else {
                UtilMetodos.messageFactoringFull("usuarioCadastradoOk", FacesMessage.SEVERITY_INFO, FacesContext.getCurrentInstance());
                UtilMetodos.messageFactoringFull("usuarioSenhaEmailAviso", FacesMessage.SEVERITY_INFO, FacesContext.getCurrentInstance());
            }

        } catch (ValidacaoExcecao e) {
            if (!StringUtils.isBlank(e.getAtributoName())) {
                UtilMetodos.messageFactoringFull(UtilMetodos.getResourceBundle(e.getMessage(), FacesContext.getCurrentInstance()), null, e.getAtributoName(), FacesMessage.SEVERITY_ERROR, FacesContext.getCurrentInstance());
            } else {
                UtilMetodos.messageFactoringFull(e.getMessage(), FacesMessage.SEVERITY_ERROR, FacesContext.getCurrentInstance());
            }
        }
        atualizarModelUsuarios();
    }

    public void atualizarModelUsuarios() {
        this.modelUsuarios = new ArrayList(usuarioBean.buscarUsuariosAbaixoPapel(loginManager.getUsuario()));
    }

    //====================
    //Table Actions
    //====================
    public void resetarSenha(ActionEvent event) {
        this.usuarioCadastro.setSenha(null);
        salvarUsuario(event);
        UtilMetodos.messageFactoringFull("usuarioSenhaEmailAviso", FacesMessage.SEVERITY_INFO, FacesContext.getCurrentInstance());
    }

    public void bloquearDesbloquearUsuario(ActionEvent event) {
        if (usuarioCadastro.equals(loginManager.getUsuario())) {
            UtilMetodos.messageFactoringFull("usuarioCadastradoBloqueadoSiMesmo", FacesMessage.SEVERITY_WARN, FacesContext.getCurrentInstance());
            init();
            return;
        }
        this.usuarioCadastro.setBloqueado(!getUsuarioCadastro().isBloqueado());
        salvarUsuario(event);
    }

    //====================
    //SelectItem
    //====================
    /**
     * Se o usuário logado for ADM, todas as opções de roles serão inseridas.
     * Se o usuário não for ADM, somente roles de menor level no papel será inserida.
     * @return
     */
    public List<SelectItem> getRoles() {
        return selectItemManager.getRoles(loginManager.getUsuario());
    }

    //=========================
    //Getters AND Setters
    //=========================
    public Usuario getUsuarioCadastro() {
        return usuarioCadastro;
    }

    public void setUsuarioCadastro(Usuario usuarioCadastro) {
        this.usuarioCadastro = usuarioCadastro;
    }

    public List<Roles> getListRoles() {
        return new ArrayList<Roles>(usuarioCadastro.getRoles());
    }

    public void setListRoles(List<Roles> listRoles) {
        usuarioCadastro.setRoles(new TreeSet<Roles>(listRoles));
    }

    public List<Usuario> getModelUsuarios() {
        if (this.modelUsuarios == null) {
            atualizarModelUsuarios();
        }
        return modelUsuarios;
    }

    public void setModelUsuarios(List<Usuario> modelUsuarios) {
        this.modelUsuarios = modelUsuarios;
    }

    public LoginManager getLoginManager() {
        return loginManager;
    }

    public void setLoginManager(LoginManager loginManager) {
        this.loginManager = loginManager;
    }

    public SelectItemManager getSelectItemManager() {
        return selectItemManager;
    }

    public void setSelectItemManager(SelectItemManager selectItemManager) {
        this.selectItemManager = selectItemManager;
    }

    public String getActionEvent() {
        return actionEvent;
    }

    public void setActionEvent(String actionEvent) {
        this.actionEvent = actionEvent;
        if (actionEvent.equals("senha")) {
            resetarSenha(null);
        } else if (actionEvent.equals("status")) {
            bloquearDesbloquearUsuario(null);
        }
    }
}
